/**
 * 工具方法
 */
// 蓝牙工具类
const BleUtils = BleUtils || {};
BleUtils.devices = [];
BleUtils.tryCount = 0; //重试次数
BleUtils.ServiceUUID = "";
BleUtils.ReadUUID = "";
BleUtils.WriteUUID = "";
BleUtils.deviceId = "";
BleUtils.connected = false;
const ERROR = {
  10000: "未初始化蓝牙适配器",
  10001: "当前蓝牙适配器不可用",
  10002: "没有找到指定设备",
  10003: "连接失败",
  10004: "	没有找到指定服务",
  10005: "没有找到指定特征",
  10006: "当前连接已断开",
  10007: "当前特征不支持此操作",
  10008: "其余所有系统上报的异常",
  10009: "Android 系统特有，系统版本低于 4.3 不支持 BLE",
  10012: "连接超时",
  10013: "连接 deviceId 为空或者是格式不正确"
}
BleUtils.connect = (tryCount) => {
  var that = BleUtils;
  console.log("第", tryCount, "次连接");
  if (tryCount != 0) {
    wx.hideLoading();
    wx.showToast({
      title: '尝试第' + tryCount + '次重连',
      icon: 'loading',
      duration: 5000,
    })
  }
  BleUtils.tryCount = tryCount;
  if (tryCount == 3) {
    console.log("重连三次了,放弃了");
    return;
  }
  //关闭当前的蓝牙模块
  wx.closeBluetoothAdapter({
    success: (res) => {
      console.log("关闭蓝牙模块成功", res);
      //重新打开蓝牙模块
      wx.openBluetoothAdapter({ //初始化 蓝牙模块  成功 和 失败的回调
        success: res => {
          console.log('初始化蓝牙成功', res)
          // that.getBluetoothAdapterState();
          that.tryConnect();
        },
        fail: err => {
          console.log('初始化蓝牙是否开启:', err);
          wx.hideLoading();
        },
        complete: function (res) {
          console.log('初始化蓝牙执行完成:', res)
        }
      })
    },
    fail: (err) => {
      console.log("关闭蓝牙模块出错", err);
    },
    complete: (res) => {
      console.log("关闭蓝牙模块完成的", res);
      // ignore
    },
  });
}
BleUtils.initBluetoothAdapte = function () {
  var that = BleUtils;
  //关闭当前的蓝牙模块

  var promise = new Promise((resolve, reject) => {
    wx.closeBluetoothAdapter({
      success: (res) => {
        console.log("关闭蓝牙模块成功", res);
        //重新打开蓝牙模块
        wx.openBluetoothAdapter({ //初始化 蓝牙模块  成功 和 失败的回调
          success: res => {
            console.log('初始化蓝牙成功', res)
            resolve(0);
            that.getBluetoothAdapterState();
          },
          fail: err => {
            console.log('初始化蓝牙是否开启:', err);
            wx.hideLoading();
            resolve(-1);
            wx.showToast({
              title: ERROR[err.errCode],
              icon: 'error'
            })
          },
          complete: function (res) {
            console.log('初始化蓝牙执行完成:', res)
          }
        })
      },
      fail: (err) => {
        console.log("关闭蓝牙模块出错", err);
      },
      complete: (res) => {
        console.log("关闭蓝牙模块完成的", res);
        // ignore
      },
    });
  });
  return promise;
}
/**
  获取本机蓝牙适配器状态 判断用户是否开启蓝牙
 */
BleUtils.getBluetoothAdapterState = function () {
  const that = BleUtils;
  console.log("获取本机蓝牙适配器状态");
  wx.getBluetoothAdapterState({
    success: res => {
      console.log('检测蓝牙是否开启成功', res)
      //discovering 是否正在搜索设备   
      //available 蓝牙适配器是否可用 
      if (res.available == false) {
        wx.showToast({
          title: '设备无法开启蓝牙连接',
          icon: 'none'
        })
        return;
      }
      if (res.discovering == false && res.available) {
        that.startBluetoothDevicesDiscovery()
      }
    },
    fail: err => {
      console.log('检测蓝牙是否开启失败:', err);
    },
    complete: (res) => {
      console.log('检测蓝牙是否开启完成:', res)
    }
  })
}
/**
 这个函数的作用就是只搜索和蓝牙锁相关的mac地址数据
 */
BleUtils.startBluetoothDevicesDiscovery = function () {
  console.log("开启搜索")
  const that = BleUtils;
  wx.startBluetoothDevicesDiscovery({
    //  services: [that.serviceId], //指定serviceId搜索
    allowDuplicatesKey: false,
    success: res => {
      console.log('搜索蓝牙信息失败', res)
      if (!res.isDiscovering) { //是否在搜索到了设备
        that.getBluetoothAdapterState()
      } else {
        that.onBluetoothDeviceFound() //设备参数返回成功 就去执行搜索设备
      }
    },
    fail: err => {
      console.log('搜索蓝牙信息失败', err)
      that.stopBluetoothDevicesDiscovery()
    },
    complete: function (res) {
      console.log('搜索蓝牙信息成功', res)
    }
  })
}
//安卓 是通过 deviceId 与mac 地址配对 然后ios是通过advertisData 通过建立  
// 这里的操作 安卓和ios建立蓝牙多是通过advertisData 转换成二进制来判断连接的
BleUtils.onBluetoothDeviceFound = function () { //搜索相对应的设备
  const that = BleUtils;
  wx.onBluetoothDeviceFound((res) => {
    console.log('搜索到的设备没配对成功', res)
    res.devices.forEach(device => {
      //过滤掉没有蓝牙名称的设备信息
      if (device.name != null && device.name != '')
        that.devices.push(device);
      if (false) {
        that.stopBluetoothDevicesDiscovery() //设备已经搜索到，停止搜索
        console.log('设备已经搜索到，停止搜索')
        that.tryConnect(); //创建连接
      }
    })
  })
}
/**
  停止蓝牙搜索
 */
BleUtils.stopBluetoothDevicesDiscovery = function () {
  console.log('停止搜索')
  wx.stopBluetoothDevicesDiscovery({
    success: function (res) {
      console.log('停止成功', res)
    },
    fail(err) {
      console.log('停止失败', err)
    },
    complete(res) {
      console.log('停止搜索执行', res)
    }
  })
}
/**
  尝试连接
*/
BleUtils.tryConnect = function () {
  var that = BleUtils;
  wx.createBLEConnection({
    deviceId: that.deviceId,
    timeout: 3000, //设置3s连接超时时间
    success: res => {
      console.log('连接蓝牙', res)
      if (res.errCode == 0) {
        wx.hideLoading();
        wx.showToast({
          title: '正在设置服务',
          icon: 'loading'
        })
        //todo 连接成功后的操作 ...
        //设置特征值
        that.getBLEDeviceServices();
      }
    },
    fail: err => {
      console.log('连接失败:', err)
      console.log('重连次数', BleUtils.tryCount);
      setTimeout(() => {
        that.connect(BleUtils.tryCount + 1);
      }, 1500)
    },
    complete: function (res) {
      console.log('连接蓝牙执行', res)
    }
  })
}
/**
 * 关闭BLE连接以及关闭适配器
 */
BleUtils.closeBLEConnection = (success) => {
  var that = BleUtils;
  return new Promise((resolve, reject) => {
    wx.closeBLEConnection({
      deviceId: that.deviceId,
      success(res) {
        console.log("关闭蓝牙连接成功", res);
        wx.closeBluetoothAdapter({
          success: success || function (res) {
            console.log("1关闭蓝牙模块成功", res);
          },
          fail: function (err) {
            console.log("1关闭蓝牙模块失败", err)
          },
          complete: function (res) {
            console.log("1关闭蓝牙模块完成", res);
          }
        })
      },
      fail(err) {
        console.log("关闭蓝牙连接失败", err);
        wx.closeBluetoothAdapter({
          success: success || function (res) {
            console.log("2关闭蓝牙模块成功", res);
          },
          fail: function (err) {
            console.log("2关闭蓝牙模块失败", err)
          },
          complete: function (res) {
            console.log("2关闭蓝牙模块完成", res);
          }
        })
      },
      complete: function (res) {
        console.log('关闭蓝牙连接完成', res)
        // resolve(0);
        // wx.showToast({
        //   title: '关闭成功',
        //   icon:'none'
        // })
      }
    })
  })

};
//获取蓝牙低功耗设备所有服务
BleUtils.getBLEDeviceServices = function () {
  var that = this
  wx.getBLEDeviceServices({
    deviceId: that.deviceId,
    success: (res) => {
      var isService = false
      for (let i = 0; i < res.services.length; i++) {
        if (that.ServiceUUID == res.services[i].uuid) {
          isService = true;
          console.log("找到服务UUID，正在读取所有特征值")
          this.getBLEDeviceCharacteristics();
        }
      }
      if (!isService) { //没有找到服务
        this.setData({
          connectState: "UUID错误"
        })

      }
    },
    fail: res => {
      console.log("失败");
      wx.showToast({
        title: '获取蓝牙服务失败',
        icon: 'none',
      })
    }
  })
};
//获取蓝牙低功耗设备某个服务中所有特征
BleUtils.getBLEDeviceCharacteristics = function () {
  const that = BleUtils;
  wx.getBLEDeviceCharacteristics({
    deviceId: that.deviceId,
    serviceId: that.ServiceUUID,
    success: (res) => {
      console.log('getBLEDeviceCharacteristics success', res.characteristics)
      for (let i = 0; i < res.characteristics.length; i++) {
        let item = res.characteristics[i]
        //console.log("this properties = ", item.properties)
        if (item.properties.read) { //该特征是否支持 read 操作
          //console.log("[Read]", item.uuid)
          console.log(item.properties.read);
          wx.readBLECharacteristicValue({
            deviceId: that.deviceId,
            serviceId: that.ServiceUUID,
            characteristicId: item.uuid,
          })
        }
        if (item.properties.notify || item.properties.indicate) { //该特征是否支持 notify 操作||该特征是否支持 indicate 操作
          if (that.ReadUUID == item.uuid) {
            wx.notifyBLECharacteristicValueChange({ //开启通知才能监听设备 characteristicValueChange 事件
              deviceId: that.deviceId,
              serviceId: that.ServiceUUID,
              characteristicId: item.uuid,
              state: true,
              success(res) {
                console.log("连接成功:", res);
                wx.hideLoading();
                that.connected = true;
                wx.showToast({
                  title: '连接成功',
                  icon: 'none',
                })
              },
              fail: res => {
                console.log("连接失败:", res);
              }
            })
          }

        }
      }
    },
    fail(res) {
      console.log("连接失败:", res);
      wx.showToast({
        title: '特征值设置失败',
        icon: 'none'
      })
    }
  })
};
BleUtils.toast = function (title = '数据加载失败...') {
  console.log("进入");
  wx.showToast({
    title,
    mask: true,
    icon: 'none',
  })
};
BleUtils.sendMsg= function(sendData) {
  var that = BleUtils;
    var promise = new Promise((resolv, reject) => {
      console.log("发送的命令：", sendData);
      let buffer =hexStringToArrayBuffer(sendData); //转16进制
      let pos = 0;
      let bytes = buffer.byteLength;
      var result = ''
      while (bytes > 0) {
        let tmpBuffer;
        if (bytes > 20) {
          tmpBuffer = buffer.slice(pos, pos + 20);
          pos += 20;
          bytes -= 20;
          wx.writeBLECharacteristicValue({
            deviceId: that.deviceId, //蓝牙设备 id
            serviceId: that.ServiceUUID, //蓝牙特征对应服务的 UUID
            characteristicId: that.WriteUUID, //蓝牙特征的 UUID
            value: tmpBuffer,
            success(res) {
              console.log('发送成功！', res);
            }
          })
          // sleep(0.02)
        } else {
          tmpBuffer = buffer.slice(pos, pos + bytes);
          pos += bytes;
          bytes -= bytes;
          wx.writeBLECharacteristicValue({
            deviceId: that.deviceId, //蓝牙设备 id
            serviceId: that.ServiceUUID, //蓝牙特征对应服务的 UUID
            characteristicId: that.WriteUUID, //蓝牙特征的 UUID
            value: tmpBuffer,
            success(res) {
              console.log('最后次发送', res)
              resolv(0);
            },
            fail: function (res) {
              console.log('发送失败', res)
              resolv(-1);
            }
          })
        }
      }
    })
    return promise;
  };
  //转16进制
function hexStringToArrayBuffer(command){
  if (!command) {
    return new ArrayBuffer(0);
  }
  var buffer = new ArrayBuffer(command.length);
  let dataView = new DataView(buffer)
  let ind = 0;
  for (var i = 0, len = command.length; i < len; i += 2) {
    let code = parseInt(command.substr(i, 2), 16)
    dataView.setUint8(ind, code)
    ind++
  }
  return buffer;
}

  /**
   * 模块化导出
   */
  export default BleUtils